import axios from 'axios'
import { MessageBox, Message } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'
import { errorAlert } from '@/utils/message'

/*
 * 一、request：
 *    1. 说明：封装对后台的请求，可以选择自动处理一些异常。
 *    2. 参数：
 *        - url：            后台地址，必填，String，如："/user/add"
 *        - params：         请求参数，必填，Object，如：{"name":"xxx"}
 *        - config：         axios参数，选填，Object，默认值：{}
 *        - auto_error_res： 是否自动处理响应错误，选填，Boolean，默认值：true
 *        - auto_error_data：是否自动处理后台错误，选填，Boolean，默认值：true
 *    3. 返回：
 *        - 成功：Promise.resolve(请求成功后的结果：response.data.result)
 *        - 失败：
 *            - 请求异常：Promise.reject(http响应错误)
 *            - 请求失败：Promise.reject(请求失败后的结果：response.data.error)
 *    4. 约定后台返回数据格式：
 *        response.data = {
 *          "success": true/false,         //请求成功或失败
 *          "result": {},                  //请求成功后的结果
 *          "error":{
 *            "code": 100001,              //请求失败错误码
 *            "message": "用户名字重复"    //请求失败描述
 *          }
 *        }
 **/

// 新建一个 axios 实例
const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
  withCredentials: true, // send cookies when cross-domain requests
  timeout: 5000 // 请求超时时间
})

// request 拦截器
service.interceptors.request.use(
  config => {
    if (store.getters.token) {
      // 每个请求头带上user-token
      // config.headers.token = getToken()
      config.headers['token'] = getToken()
    }
    return config
  },
  error => {
    // 处理请求错误
    // console.log(error) // for debug
    return Promise.reject(error)
  }
)

// response 拦截器
service.interceptors.response.use(
  /**
   * 如果您想获得http信息，例如头信息或状态信息
   * 请 return  response => response
   */
  /**
   * 通过自定义代码确定请求状态
   *这里只是一个例子
   *您还可以通过HTTP状态代码来判断状态
   */
  response => {
    const data = response.data
    // 如果data.success为false，则判断为错误。
    if (!data.success) {
      data.error = data.error || {}
      // token失效
      if (
        data.error.code === 401 &&
        data.error.message === '未登录或登陆失效，请先登录'
      ) {
        // to re-login
        MessageBox.confirm(
          '您已经注销，您可以取消以停留在此页面，或再次登录',
          '确认注销',
          {
            confirmButtonText: '重新登陆',
            cancelButtonText: '取消',
            type: 'warning'
          }
        ).then(() => {
          store.dispatch('user/resetToken').then(() => {
            location.reload()
          })
        })
        return Promise.reject(data.error)
      }
      Message({
        message: data.error.message || '未定义的后端错误，请联系管理员！',
        type: 'error',
        duration: 5 * 1000
      })
      return Promise.reject(
        data.error.message || '未定义的后端错误，请联系管理员！'
      )
    } else {
      return data.result
    }
  },
  error => {
    // console.log(error.message)
    const err_status = error.response.status || -100
    if (err_status === 500 || err_status === 403 || err_status === 404) {
      errorAlert(
        err_status + '：' + error.response.data.message || '未知的服务器错误'
      )
      return Promise.reject(error)
    }
    if (err_status === 504) {
      errorAlert(err_status + '：' + '接口超时')
      return Promise.reject(error.response.data.message)
    }
    errorAlert(
      err_status + '：' + error.response.data.message || '未知的服务器错误'
    )
    return Promise.reject(error.response)
  }
)

export const postRequest = (url, params, is_object = true) => {
  const param = params || {}
  if (is_object) {
    return service({
      method: 'post',
      url: url,
      data: param
    })
  } else {
    return service({
      method: 'post',
      url: url,
      data: params,
      transformRequest: [
        function(data) {
          let ret = ''
          for (const it in data) {
            ret +=
              encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&'
          }
          return ret
        }
      ],
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
      }
    })
  }
}
export const uploadFileRequest = (url, params) => {
  return service({
    method: 'post',
    url: url,
    data: params,
    headers: {
      'Content-Type': 'multipart/form-data'
    }
  })
}
export const putRequest = (url, params, is_object = true) => {
  const param = params || {}
  if (!is_object) {
    return service({
      method: 'put',
      url: url,
      data: param,
      transformRequest: [
        function(data) {
          let ret = ''
          for (const it in data) {
            ret +=
              encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&'
          }
          return ret
        }
      ],
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
      }
    })
  } else {
    return service({
      method: 'put',
      url: url,
      data: param
    })
  }
}
export const deleteRequest = (url, params, is_object = true) => {
  const param = params || {}
  // return service({
  //   method: 'delete',
  //   url: url,
  //   params: param
  // })
  if (!is_object) {
    return service({
      method: 'delete',
      url: url,
      data: param,
      transformRequest: [
        function(data) {
          let ret = ''
          for (const it in data) {
            ret +=
              encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&'
          }
          return ret
        }
      ],
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
      }
    })
  } else {
    return service({
      method: 'delete',
      url: url,
      data: param
    })
  }
}
export const getRequest = (url, params) => {
  const param = params || {}
  return service({
    method: 'get',
    url: url,
    params: param
  })
}

export default service
